iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Cloud Native

【하나, 둘, ready, get set, go】系列 第 25

【하나, 둘, ready, get set, go】Day 25 - 將 API 結合 SQL 資料庫

  • 分享至 

  • xImage
  •  

前情提要

昨天體驗使用 Gin 來撰寫第一支 Web Backend API

今天要來整合先前寫的 SQL 資料庫,透過呼叫 API,來與 SQL 資料庫進行互動

實際操作

目前我們已經寫好了 repository 裡的 album.go

以及目前我們跟 repository 的互動都寫在 main.go 裡面,現在我們要來將其移到對應的 Handler Function 內

Create

我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數

並使用 data 內的值當作我們新增到 Album 內各欄位的值

如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳新增成功訊息

func Create(c *gin.Context) {
    type param struct {
        Title       string `json:"title"`
        Artist      string `json:"artist"`
        ReleaseDate string `json:"releaseDate"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Create Failed" + err.Error(),
        })
        return
    }

    album := database.Album{
        ID:          uuid.New().String(),
        Title:       data.Title,
        Artist:      data.Artist,
        ReleaseDate: data.ReleaseDate,
    }

    err = repository.Create(album)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Create Failed,Error:" + err.Error(),
        })
        return
    }

    c.JSON(http.StatusOK, gin.H{
        "message": "Create Success",
    })
}

Create

▲ Postman 測試結果

Get

我們透過使用 Gin 提供的 Query 來取得網址上的 Query 參數值,並作為變數 albumId

並使用 albumId 來向 SQL 資料庫進行篩選符合的值

如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳讀取成功訊息

func Get(c *gin.Context) {
    albumId := c.Query("id")    
    
    result, err := repository.Read(albumId)
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Success,No record found",
    	})
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Get Success",
        "albums":  result,
    })
}

Get

▲ Postman 測試結果

Get All

func GetAll(c *gin.Context) {
    result, err := repository.ReadAll()
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Success,No record found",
        })
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Get Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Get Success",
        "albums":  result,
    })
}

Get All

▲ Postman 測試結果

Update

我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數

並使用 data 內的值當作我們更新 Album 內各欄位的值 (除 id 欄位)

如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳更新成功訊息

func Update(c *gin.Context) {
    type param struct {
        ID          string `json:"id"`
        Title       string `json:"title"`
        Artist      string `json:"artist"`
        ReleaseDate string `json:"releaseDate"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Failed,Error:" + err.Error(),
        })
        return
    }    
    
    result, err := repository.Read(data.ID)
    if errors.Is(err, gorm.ErrRecordNotFound) {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Success,No record found",
        })
        return
    } else if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Update Failed,Error:" + err.Error(),
        })
        return
    }    
    
    repository.Update(result, database.Album{
        Title:       data.Title,
        Artist:      data.Artist,
        ReleaseDate: data.ReleaseDate,
    })   
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Update Success",
    })
}

Update

▲ Postman 測試結果

Delete

我們透過定義一個 private 的 param struct 以及使用 Gin 提供的 BindJSON 來解析 HTTP Body 傳進來的 JSON Object 作為 data 變數

並使用 data 內的值 (id) 當作我們從 SQL 資料庫篩選的值

如果有發生錯誤,則以 JSON 回傳錯誤訊息,反之,則以 JSON 回傳刪除成功訊息

func Delete(c *gin.Context) {
    type param struct {
        ID string `json:"id"`
    }
    var data param
    err := c.BindJSON(&data)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Delete Failed,Error:" + err.Error(),
        })
        return
    }    
    
    repository.Delete(data.ID)    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Delete Success",
    })
}

Delete

▲ Postman 測試結果

Delete All

func DeleteAll(c *gin.Context) {
    err := repository.DeleteAll()
    if err != nil {
        c.JSON(http.StatusOK, gin.H{
            "message": "Delete All Failed,Error:" + err.Error(),
        })
        return
    }    
    
    c.JSON(http.StatusOK, gin.H{
        "message": "Delete All Success",
    })
}

Delete All

▲ Postman 測試結果

總結

今天我們將先前寫的 SQL 資料庫進行整合

接下來就要開始進到跟本次參賽主題 Cloud Native 相關的內容了

明天要來我們寫好的 Backend API 包成多架構的 Docker Image,方便後面我們部署到 Kubernetes 上

那麼就明天見啦~


上一篇
【하나, 둘, ready, get set, go】Day 24 - 使用 Gin 撰寫第一支 Web Backend API
下一篇
【하나, 둘, ready, get set, go】Day 26 - 將服務打包成多架構 Docker Image
系列文
【하나, 둘, ready, get set, go】30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言